package com.zhifei.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.zhifei.common.core.redis.RedisCache;
import com.zhifei.common.utils.DateUtils;
import com.zhifei.common.utils.Result;
import com.zhifei.system.domain.HlyVendorEntity;
import com.zhifei.system.service.HlyService;
import com.zhifei.system.service.HlyVendorService;
import com.zhifei.system.service.JdService;
import com.zhifei.system.util.hly.HlyAccessTokenResult;
import com.zhifei.system.util.hly.HlyVendorBankVo;
import com.zhifei.system.util.hly.HlyVendorVo;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class HlyServiceImpl implements HlyService {

    @Autowired
    private HlyVendorService hlyVendorService;
    @Autowired
    private JdService jdService;
    @Autowired
    private RedisCache redisCache;

    public static final String clientId = "f182b886-77fc-46bd-9d3c-9e3e71bb76a5";//企业ID
    public static final String securet = "NGE1YmUxMDctZTI2NS00MGVkLTk1NTktYmJkMzVjMmQwOGQ4";//企业密钥
    public static final String tokenUrl = "https://api.huilianyi.com/gateway/oauth/token";//获取token地址

    public static final int MAX_TIME_OUT = 1000 * 120;

    @Override
    public Result listVendor() {
        String response = this.getRequest("https://api.huilianyi.com/gateway/api/open/vendor");
        List<HlyVendorVo> hlyVendorVoList = JSONArray.parseArray(response,HlyVendorVo.class);
        List<HlyVendorVo> hlyVendorList = new ArrayList<>();
        hlyVendorList.addAll(hlyVendorVoList);
        List<String> vendorNumberList = hlyVendorVoList.stream().map(HlyVendorVo::getVendorNumber).collect(Collectors.toList());
        if(vendorNumberList==null || vendorNumberList.size()==0){
            return Result.success();
        }
        List<HlyVendorEntity> hlyVendorEntityList = hlyVendorService.listInVendorNumber(vendorNumberList);
        for(HlyVendorEntity hlyVendorEntity : hlyVendorEntityList){
            if(hlyVendorVoList!=null && hlyVendorVoList.size()>0){
                for(HlyVendorVo hlyVendorVo : hlyVendorVoList){
                    if(hlyVendorEntity.getVendorNumber().equals(hlyVendorVo.getVendorNumber())){
                        hlyVendorList.remove(hlyVendorVo);//移除已同步的供应商
                    }
                }
            }
        }
        for(HlyVendorVo hlyVendorVo : hlyVendorList){
            String vendorNumber = hlyVendorVo.getVendorNumber();
            String vendorName = hlyVendorVo.getVendorName();
            String bankAccount = null;
            String venBankNumberName = null;
            String bankOperatorNumber = null;
            String bankOpeningBank = null;
            if(hlyVendorVo.getBankAccounts()!=null && hlyVendorVo.getBankAccounts().size()>0){
                HlyVendorBankVo hlyVendorBankVo = hlyVendorVo.getBankAccounts().get(0);
                bankAccount = hlyVendorBankVo.getBankAccount();
                venBankNumberName = hlyVendorBankVo.getVenBankNumberName();
                bankOperatorNumber = hlyVendorBankVo.getBankOperatorNumber();
                bankOpeningBank = hlyVendorBankVo.getBankOpeningBank();
            }
            //新增到金蝶供应商
            jdService.addK3cloudVendor(vendorNumber,vendorName,bankAccount,venBankNumberName,bankOperatorNumber,bankOpeningBank);
            //插入到汇联易供应商表
            HlyVendorEntity hlyVendorEntity = new HlyVendorEntity();
            hlyVendorEntity.setVendorNumber(vendorNumber);
            hlyVendorEntity.setVendorName(vendorName);
            hlyVendorEntity.setBankAccount(bankAccount);
            hlyVendorEntity.setVenBankNumberName(venBankNumberName);
            hlyVendorEntity.setBankOperatorNumber(bankOperatorNumber);
            hlyVendorEntity.setBankOpeningBank(bankOpeningBank);
            hlyVendorService.save(hlyVendorEntity);
        }
        return Result.success(response);
    }

    public HlyAccessTokenResult getToken(){
        // 获取redis中token
        HlyAccessTokenResult corpAccessTokenResult = redisCache.getCacheObject("hly_access_token");
        // 判断token是否有值
        if (corpAccessTokenResult==null) {
            HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
            httpRequestFactory.setConnectionRequestTimeout(MAX_TIME_OUT);
            httpRequestFactory.setConnectTimeout(MAX_TIME_OUT);
            httpRequestFactory.setReadTimeout(MAX_TIME_OUT);
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.setRequestFactory(httpRequestFactory);

            HttpHeaders httpHeaders = new HttpHeaders();
            String authStr = clientId.concat(":").concat(securet);
            String authStrEnc = new String(Base64.encodeBase64(authStr.getBytes()));
            httpHeaders.set("Authorization", "Basic ".concat(authStrEnc));

            MultiValueMap<String, String> formData = new LinkedMultiValueMap();
            formData.add("grant_type", "client_credentials");
            formData.add("scope", "write");

            HttpEntity httpEntity =  new HttpEntity(formData, httpHeaders);
            ResponseEntity<String> exchange = restTemplate.exchange(tokenUrl, HttpMethod.POST, httpEntity, String.class);
            String respone = exchange.getBody();
            corpAccessTokenResult = JSON.parseObject(respone, HlyAccessTokenResult.class);
            if (!Objects.isNull(corpAccessTokenResult) && "0".equals(corpAccessTokenResult.getErrorCode())) {
                redisCache.setCacheObject("hly_access_token", corpAccessTokenResult, 86400, TimeUnit.SECONDS);
            }
        }
        return corpAccessTokenResult;
    }

    public String getRequest(String url){
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        httpRequestFactory.setConnectionRequestTimeout(MAX_TIME_OUT);
        httpRequestFactory.setConnectTimeout(MAX_TIME_OUT);
        httpRequestFactory.setReadTimeout(MAX_TIME_OUT);
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setRequestFactory(httpRequestFactory);
        HlyAccessTokenResult hlyAccessTokenResult = this.getToken();
        if(!"0".equals(hlyAccessTokenResult.getErrorCode())){
            return null;
        }
        //组装请求参数,可以封装成实体类或者用map或者JSONObject等
        JSONObject jsonObject = new JSONObject();
        String nowDate = DateUtils.getDate();
        jsonObject.put("startDate", nowDate+" 00:00:00");
        jsonObject.put("endDate",nowDate+" 23:59:59");
        jsonObject.put("page",1);
        jsonObject.put("size",100);
        url = this.parseJsonToUrlParams(url+"?access_token="+hlyAccessTokenResult.getAccess_token(),jsonObject);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Authorization", "Bearer  ".concat(hlyAccessTokenResult.getAccess_token()));
        httpHeaders.set("Content-Type","application/json");
        HttpEntity httpEntity = new HttpEntity(null, httpHeaders);
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
        String respone = exchange.getBody();
        return respone;
    }

    public String parseJsonToUrlParams(String url,JSONObject jsonObject) {
        try {
            Iterator it = jsonObject.keySet().iterator();
            String paramStr = "";
            while (it.hasNext()) {
                String key = (String) it.next();
                String value = jsonObject.getString(key);
                paramStr += "&" + key + "=" + value;
            }
            return url+paramStr;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

}
